<template>
  <div class="carousel-container relative overflow-hidden" :style="containerStyle" @mouseenter="isHovered = true"
    @mouseleave="isHovered = false">
    <!-- 加载状态显示 -->
    <div v-if="isLoading" class="absolute inset-0 flex justify-center items-center bg-white/80">
      <div class="text-center">
        <div class="inline-block animate-spin rounded-full h-12 w-12 border-t-2 border-b-2"
          :style="{ borderColor: props.primaryColor }" aria-label="Loading"></div>
        <p class="mt-4 text-lg text-gray-600">正在加载轮播图数据...</p>
      </div>
    </div>

    <!-- 轮播图内容 -->
    <div class="carousel-slides flex transition-transform duration-500 ease-in-out" :style="slidesStyle">
      <div v-for="(slide, index) in slidesWithUrls" :key="index" class="carousel-slide min-w-full h-full relative">
        <!-- 图片 -->
        <img :src="slide.imageUrl" :alt="slide.alt || `轮播图片${index + 1}`"
          class="w-full h-full object-cover transition-opacity duration-500" :style="{
            position: props.transitionEffect === 'fade' ? 'absolute' : 'relative',
            top: props.transitionEffect === 'fade' ? 0 : 'auto',
            left: props.transitionEffect === 'fade' ? 0 : 'auto',
            opacity: props.transitionEffect === 'fade' && currentIndex.value !== index ? 0 : 1,
            transitionDuration: `${props.transitionDuration}ms`
          }" @error="handleImageError(index)">

        <!-- 文字覆盖层 -->
        <div v-if="slide.title || slide.description"
          class="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent flex flex-col justify-end p-6 md:p-8"
          :style="overlayStyle">
          <h3 v-if="slide.title" class="text-white text-xl md:text-2xl font-bold mb-2" :style="titleStyle">
            {{ slide.title }}
          </h3>
          <p v-if="slide.description" class="text-white/90 mb-4" :style="descriptionStyle">
            {{ slide.description }}
          </p>
          <button v-if="slide.buttonText"
            class="inline-flex items-center px-4 py-2 rounded-md text-sm font-medium transition-colors duration-200"
            :style="buttonStyle" @click.stop="handleButtonClick(slide, index)">
            {{ slide.buttonText }}
            <i v-if="showButtonIcon" class="fa fa-arrow-right ml-2"></i>
          </button>
        </div>
      </div>
    </div>

    <!-- 刷新按钮（仅在设置了数据源URL时显示） -->
    <button v-if="props.dataSourceUrl && !isLoading"
      class="absolute bottom-4 right-4 z-10 px-4 py-2 bg-white/80 hover:bg-white text-gray-700 rounded-md text-sm flex items-center shadow-lg transition-all duration-200"
      @click="refresh">
      <i class="fa fa-refresh mr-2"></i>
      刷新轮播图
    </button>

    <!-- 前进后退按钮 -->
    <button v-if="showControls"
      class="absolute top-1/2 left-4 transform -translate-y-1/2 w-10 h-10 rounded-full bg-white/30 hover:bg-white/50 flex items-center justify-center text-white transition-all duration-200"
      :style="controlButtonStyle" @click.stop="prevSlide" title="上一张">
      <i class="fa fa-chevron-left"></i>
    </button>

    <button v-if="showControls"
      class="absolute top-1/2 right-4 transform -translate-y-1/2 w-10 h-10 rounded-full bg-white/30 hover:bg-white/50 flex items-center justify-center text-white transition-all duration-200"
      :style="controlButtonStyle" @click.stop="nextSlide" title="下一张">
      <i class="fa fa-chevron-right"></i>
    </button>

    <!-- 指示器 -->
    <div v-if="showIndicators" class="absolute bottom-4 left-0 right-0 flex justify-center gap-2">
      <button v-if="showIndicators && slidesWithUrls.length > 0" v-for="(slide, index) in slidesWithUrls" :key="index"
        class="w-3 h-3 rounded-full transition-all duration-200" :style="getIndicatorStyle(index)"
        @click.stop="goToSlide(index)" :title="`切换到第${index + 1}张`"></button>
    </div>

    <!-- 空状态显示 -->
    <div v-if="!isLoading && slidesWithUrls.length === 0"
      class="absolute inset-0 flex flex-col justify-center items-center bg-gray-50">
      <i class="fa fa-picture-o text-6xl text-gray-300 mb-4"></i>
      <p class="text-lg text-gray-500">暂无轮播图数据</p>
      <button v-if="props.dataSourceUrl"
        class="mt-4 px-4 py-2 bg-primary text-white rounded-md flex items-center hover:bg-primary/90 transition-colors duration-200"
        @click="refresh">
        <i class="fa fa-refresh mr-2"></i>
        刷新数据
      </button>
    </div>
  </div>
</template>

<script>
import { defineComponent, ref, computed, onMounted, onBeforeUnmount, watch } from 'vue';

export default defineComponent({
  name: 'ImageCarousel',
  // 低代码平台元数据
  lowcode: {
    meta: {
      name: 'image-carousel',
      displayName: '轮播图',
      description: '响应式图片轮播组件，支持自动播放、手动控制和自定义样式',
      icon: 'fa-image',
      category: '媒体展示',
      version: '1.0.0',
      isContainer: false
    },

    configPanel: [
      {
        title: '基本配置',
        fields: [
          {
            name: 'primaryColor',
            label: '主题色',
            type: 'color',
            defaultValue: '#165DFF'
          },
          {
            name: 'slides',
            label: '轮播图片',
            type: 'array',
            defaultValue: [
              {
                imageUrl: 'https://picsum.photos/seed/carousel1/1200/600',
                alt: '轮播图片1',
                title: '第一张轮播图',
                description: '这是第一张轮播图的描述文字',
                buttonText: '了解更多'
              },
              {
                imageUrl: 'https://picsum.photos/seed/carousel2/1200/600',
                alt: '轮播图片2',
                title: '第二张轮播图',
                description: '这是第二张轮播图的描述文字',
                buttonText: '立即查看'
              },
              {
                imageUrl: 'https://picsum.photos/seed/carousel3/1200/600',
                alt: '轮播图片3',
                title: '第三张轮播图',
                description: '这是第三张轮播图的描述文字',
                buttonText: '查看详情'
              }
            ]
          },
          {
            name: 'height',
            label: '轮播图高度(px)',
            type: 'number',
            min: 200,
            max: 1000,
            defaultValue: 400
          }
        ]
      },
      {
        title: '数据源配置',
        fields: [

          {
            name: 'dataSourceUrl',
            label: '数据源URL',
            type: 'text',
            defaultValue: '',
            description: '当数据源类型为API或JSON时填写'
          },
          {
            name: 'autoLoad',
            label: '自动加载',
            type: 'boolean',
            defaultValue: true,
            description: '组件挂载时自动加载数据'
          }
        ]
      },
      {
        title: '播放设置',
        fields: [
          {
            name: 'autoPlay',
            label: '自动播放',
            type: 'boolean',
            defaultValue: true
          },
          {
            name: 'autoPlayInterval',
            label: '播放间隔(秒)',
            type: 'number',
            min: 1,
            max: 10,
            step: 0.5,
            defaultValue: 3
          },
          {
            name: 'transitionEffect',
            label: '过渡效果',
            type: 'select',
            options: [
              { label: '淡入淡出', value: 'fade' },
              { label: '滑动', value: 'slide' }
            ],
            defaultValue: 'slide'
          },
          {
            name: 'transitionDuration',
            label: '过渡时长(毫秒)',
            type: 'number',
            min: 100,
            max: 2000,
            defaultValue: 500
          }
        ]
      },
      {
        title: '控制设置',
        fields: [
          {
            name: 'showControls',
            label: '显示控制按钮',
            type: 'boolean',
            defaultValue: true
          },
          {
            name: 'showIndicators',
            label: '显示指示器',
            type: 'boolean',
            defaultValue: true
          },
          {
            name: 'pauseOnHover',
            label: '鼠标悬停暂停',
            type: 'boolean',
            defaultValue: true
          }
        ]
      },
      {
        title: '文字样式',
        fields: [
          {
            name: 'showOverlay',
            label: '显示文字覆盖层',
            type: 'boolean',
            defaultValue: true
          },
          {
            name: 'overlayBgColor',
            label: '覆盖层背景色',
            type: 'color',
            defaultValue: 'rgba(0, 0, 0, 0.5)'
          },
          {
            name: 'titleColor',
            label: '标题颜色',
            type: 'color',
            defaultValue: '#ffffff'
          },
          {
            name: 'descriptionColor',
            label: '描述文字颜色',
            type: 'color',
            defaultValue: 'rgba(255, 255, 255, 0.9)'
          },
          {
            name: 'showButtonIcon',
            label: '显示按钮图标',
            type: 'boolean',
            defaultValue: true
          }
        ]
      }
    ],

    events: [
      {
        name: 'slideChanged',
        label: '轮播图切换',
        description: '当轮播图切换到新的幻灯片时触发',
        parameters: [
          { name: 'slide', type: 'object', description: '当前幻灯片对象' },
          { name: 'index', type: 'number', description: '当前幻灯片索引' }
        ]
      },
      {
        name: 'buttonClick',
        label: '按钮点击',
        description: '当点击幻灯片上的按钮时触发',
        parameters: [
          { name: 'slide', type: 'object', description: '当前幻灯片对象' },
          { name: 'index', type: 'number', description: '当前幻灯片索引' }
        ]
      },
      {
        name: 'dataLoaded',
        label: '数据加载成功',
        description: '从数据源加载数据成功时触发',
        parameters: [
          { name: 'data', type: 'object', description: '加载的完整数据' }
        ]
      },
      {
        name: 'dataLoadError',
        label: '数据加载失败',
        description: '从数据源加载数据失败时触发',
        parameters: [
          { name: 'error', type: 'object', description: '错误信息' }
        ]
      }
    ],

    actions: [
      {
        name: 'nextSlide',
        label: '下一张',
        description: '切换到下一张幻灯片'
      },
      {
        name: 'prevSlide',
        label: '上一张',
        description: '切换到上一张幻灯片'
      },
      {
        name: 'goToSlide',
        label: '跳转到指定幻灯片',
        description: '根据索引跳转到指定的幻灯片',
        parameters: [
          { name: 'index', type: 'number', required: true, description: '目标幻灯片索引' }
        ]
      },
      {
        name: 'startAutoPlay',
        label: '开始自动播放',
        description: '开始自动播放轮播图'
      },
      {
        name: 'stopAutoPlay',
        label: '停止自动播放',
        description: '停止自动播放轮播图'
      }
    ]
  },

  props: {
    // 基本配置
    primaryColor: {
      type: String,
      default: '#165DFF'
    },

    slides: {
      type: Array,
      default: () => [
        {
          imageUrl: 'https://picsum.photos/seed/carousel1/1200/600',
          alt: '轮播图片1',
          title: '第一张轮播图',
          description: '这是第一张轮播图的描述文字',
          buttonText: '了解更多'
        },
        {
          imageUrl: 'https://picsum.photos/seed/carousel2/1200/600',
          alt: '轮播图片2',
          title: '第二张轮播图',
          description: '这是第二张轮播图的描述文字',
          buttonText: '立即查看'
        },
        {
          imageUrl: 'https://picsum.photos/seed/carousel3/1200/600',
          alt: '轮播图片3',
          title: '第三张轮播图',
          description: '这是第三张轮播图的描述文字',
          buttonText: '查看详情'
        }
      ]
    },

    height: {
      type: Number,
      default: 400,
      validator: (value) => value >= 200 && value <= 1000
    },

    children: {
      type: Array,
      default: () => []
    },



    dataSourceUrl: {
      type: String,
      default: ''
    },

    autoLoad: {
      type: Boolean,
      default: true
    },

    // 播放设置
    autoPlay: {
      type: Boolean,
      default: true
    },

    autoPlayInterval: {
      type: Number,
      default: 3,
      validator: (value) => value >= 1 && value <= 10
    },

    transitionEffect: {
      type: String,
      default: 'slide',
      validator: (value) => ['fade', 'slide'].includes(value)
    },

    transitionDuration: {
      type: Number,
      default: 500,
      validator: (value) => value >= 100 && value <= 2000
    },

    // 控制设置
    showControls: {
      type: Boolean,
      default: true
    },

    showIndicators: {
      type: Boolean,
      default: true
    },

    pauseOnHover: {
      type: Boolean,
      default: true
    },

    // 文字样式
    showOverlay: {
      type: Boolean,
      default: true
    },

    overlayBgColor: {
      type: String,
      default: 'rgba(0, 0, 0, 0.5)'
    },

    titleColor: {
      type: String,
      default: '#ffffff'
    },

    descriptionColor: {
      type: String,
      default: 'rgba(255, 255, 255, 0.9)'
    },

    showButtonIcon: {
      type: Boolean,
      default: true
    }
  },

  setup(props, { emit }) {
    // 响应式数据
    const currentIndex = ref(0);
    const autoPlayTimer = ref(null);
    const isHovered = ref(false);
    const slidesWithUrls = ref([]);
    const isLoading = ref(false);
    const originalSlides = ref([]);

    // 从数据源加载数据
    const loadDataFromSource = async () => {
      if (!props.dataSourceUrl) {
        emit('dataLoadError', { message: '数据源URL不能为空' });
        return;
      }

      isLoading.value = true;

      try {
        const response = await fetch(props.dataSourceUrl);
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();

        // 验证数据格式并更新
        if (data.slides && Array.isArray(data.slides)) {
          slidesWithUrls.value = data.slides;
          // 重置到第一张幻灯片
          currentIndex.value = 0;
        }

        emit('dataLoaded', data);
      } catch (error) {
        console.error('加载数据失败:', error);
        emit('dataLoadError', { message: error.message });
      } finally {
        isLoading.value = false;
      }
    };

    // 刷新数据
    const refresh = () => {
      if (props.dataSourceUrl) {
        loadDataFromSource();
      }
    };

    // 恢复原始数据
    const restoreOriginalData = () => {
      slidesWithUrls.value = [...originalSlides.value];
      currentIndex.value = 0;
    };

    // 处理图片错误，使用占位图
    const handleImageError = (index) => {
      if (slidesWithUrls.value[index]) {
        slidesWithUrls.value[index].imageUrl = 'https://picsum.photos/seed/placeholder/1200/600';
      }
    };

    // 处理按钮点击
    const handleButtonClick = (slide, index) => {
      emit('buttonClick', { slide, index });
    };

    // 切换到下一张
    const nextSlide = () => {
      const newIndex = (currentIndex.value + 1) % slidesWithUrls.value.length;
      currentIndex.value = newIndex;
      emit('slideChanged', {
        slide: slidesWithUrls.value[newIndex],
        index: newIndex
      });
    };

    // 切换到上一张
    const prevSlide = () => {
      const newIndex = (currentIndex.value - 1 + slidesWithUrls.value.length) % slidesWithUrls.value.length;
      currentIndex.value = newIndex;
      emit('slideChanged', {
        slide: slidesWithUrls.value[newIndex],
        index: newIndex
      });
    };

    // 跳转到指定幻灯片
    const goToSlide = (index) => {
      if (index >= 0 && index < slidesWithUrls.value.length) {
        currentIndex.value = index;
        emit('slideChanged', {
          slide: slidesWithUrls.value[index],
          index
        });
      }
    };

    // 开始自动播放
    const startAutoPlay = () => {
      if (autoPlayTimer.value) {
        clearInterval(autoPlayTimer.value);
      }

      if (props.autoPlay && !isHovered.value) {
        autoPlayTimer.value = setInterval(() => {
          nextSlide();
        }, props.autoPlayInterval * 1000);
      }
    };

    // 停止自动播放
    const stopAutoPlay = () => {
      if (autoPlayTimer.value) {
        clearInterval(autoPlayTimer.value);
        autoPlayTimer.value = null;
      }
    };

    // 计算属性
    const containerStyle = computed(() => {
      return {
        height: `${props.height}px`
      };
    });

    const slidesStyle = computed(() => {
      if (props.transitionEffect === 'slide') {
        return {
          transform: `translateX(-${currentIndex.value * 100}%)`,
          transitionDuration: `${props.transitionDuration}ms`
        };
      }
      return {};
    });

    // 为了正确实现淡入淡出效果，我们需要移除imageStyle计算属性
    // 淡入淡出效果将在模板中通过v-for循环的index单独处理

    const overlayStyle = computed(() => {
      return props.showOverlay ? {} : { display: 'none' };
    });

    const titleStyle = computed(() => {
      return {
        color: props.titleColor
      };
    });

    const descriptionStyle = computed(() => {
      return {
        color: props.descriptionColor
      };
    });

    const buttonStyle = computed(() => {
      return {
        backgroundColor: props.primaryColor,
        color: '#ffffff'
      };
    });

    const controlButtonStyle = computed(() => {
      return {
        backgroundColor: 'rgba(255, 255, 255, 0.3)',
        color: '#ffffff'
      };
    });

    const getIndicatorStyle = (index) => {
      return {
        backgroundColor: index === currentIndex.value ? props.primaryColor : 'rgba(255, 255, 255, 0.5)',
        width: index === currentIndex.value ? '24px' : '8px',
        borderRadius: '4px'
      };
    };

    // 监听属性变化
    watch([() => props.slides], () => {
      slidesWithUrls.value = [...props.slides];
    }, { immediate: true });

    watch([() => props.autoPlay, () => props.autoPlayInterval, isHovered], () => {
      if (props.autoPlay && !isHovered.value) {
        startAutoPlay();
      } else {
        stopAutoPlay();
      }
    });



    // 监听数据源URL变化
    watch(() => props.dataSourceUrl, (newUrl) => {
      if (newUrl) {
        loadDataFromSource();
      }
    });

    // 生命周期
    onMounted(() => {
      // 保存原始静态数据
      originalSlides.value = [...props.slides];
      slidesWithUrls.value = [...props.slides];

      // 如果启用了自动加载且有数据源URL，则加载数据
      if (props.autoLoad && props.dataSourceUrl) {
        loadDataFromSource();
      }

      if (props.autoPlay) {
        startAutoPlay();
      }
    });

    onBeforeUnmount(() => {
      stopAutoPlay();
    });

    return {
      currentIndex,
      isHovered,
      slidesWithUrls,
      isLoading,
      containerStyle,
      slidesStyle,
      overlayStyle,
      titleStyle,
      descriptionStyle,
      buttonStyle,
      controlButtonStyle,
      handleImageError,
      handleButtonClick,
      nextSlide,
      prevSlide,
      goToSlide,
      startAutoPlay,
      stopAutoPlay,
      getIndicatorStyle,
      refresh,
      props
    };
  }
});
</script>

<style scoped>
/* 轮播图容器 */
.carousel-container {
  position: relative;
  overflow: hidden;
  width: 100%;
  user-select: none;
}

/* 轮播图滑动容器 */
.carousel-slides {
  display: flex;
  height: 100%;
  transition-timing-function: ease-in-out;
}

/* 单个轮播图 */
.carousel-slide {
  min-width: 100%;
  height: 100%;
  position: relative;
}

/* 图片样式 */
.carousel-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 覆盖层样式 */
.carousel-slide .bg-gradient-to-t {
  background: linear-gradient(to top, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.2), transparent);
}

/* 控制按钮样式 */
.carousel-container button {
  cursor: pointer;
  border: none;
  outline: none;
}

.carousel-container button:hover {
  background-color: rgba(255, 255, 255, 0.5) !important;
}

/* 指示器样式 */
.carousel-container .w-3.h-3.rounded-full {
  transition: all 0.3s ease;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .carousel-slide .p-6 {
    padding: 1rem !important;
  }

  .carousel-slide .text-xl {
    font-size: 1.25rem !important;
  }

  .carousel-slide .text-2xl {
    font-size: 1.5rem !important;
  }

  .carousel-container .w-10.h-10 {
    width: 36px !important;
    height: 36px !important;
  }
}
</style>